package com.example.h9iserver.service.springAi;

import com.example.h9iserver.service.springAi.advisors.MyLoggerAdvisor;
import com.example.h9iserver.service.springAi.advisors.ReReadingAdvisor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.InMemoryChatMemory;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.ollama.OllamaChatModel;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;

import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID_KEY;
import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_RETRIEVE_SIZE_KEY;

@Service
@Slf4j
public class AiChatService {

    private ChatModel chatModel;

    private ChatClient chatClient;

    private final String SYSTEM_PROMPT = "你是恋爱顾问";

    public AiChatService(ChatClient.Builder builder, OllamaChatModel ollamaChatModel) {
        ChatMemory chatMemory = new InMemoryChatMemory();
        chatClient = builder.defaultSystem(SYSTEM_PROMPT).defaultAdvisors(
                new MessageChatMemoryAdvisor(chatMemory),
                new ReReadingAdvisor(),
                new MyLoggerAdvisor()
        ).build();
        chatModel = ollamaChatModel;
    }


    /**
     * 多轮对话示例
     *
     * @param conversationId 会话id
     * @param userText 用户提示词
     */
    public String chatWithChatMemory(Long conversationId, String userText) {
        return chatClient.prompt()
                .advisors(advisor -> advisor.param(CHAT_MEMORY_CONVERSATION_ID_KEY, conversationId)
                        .param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 1))
                .user(userText)
                .call()
                .content();
    }
    /**
     * 多轮对话流式输出版本
     *
     * @param conversationId 会话id，用于维持上下文
     * @param userText 用户提示词
     */
    public Flux<String> streamChatWithMemory(Long conversationId, String userText) {
        return chatClient.prompt()
                .advisors(advisor -> advisor
                        .param(CHAT_MEMORY_CONVERSATION_ID_KEY, conversationId)
                        .param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 1))
                .user(userText)
                // 使用流式调用
                .stream().chatResponse().map(item -> {
                    String text = item.getResult().getOutput().getText();
                    return text.isEmpty() ? "\n" : text;
                });
    }

    /**
     * 修改默认系统提示词
     *
     * @param systemText 提示词
     */
    public void editSystemDefaultText(String systemText) {
        ChatClient chatClientTemp = ChatClient.builder(chatModel).defaultSystem("你是{param}顾问").build();
        String content = chatClientTemp.prompt().system(sp -> sp.param("param", systemText))
                .user("列举一些现象")
                .call()
                .content();
    }

    /**
     * 将AI输出转化为自定义Java类
     *
     * @param userText 用户提示词
     */
    public void entitySample(String userText) {
        List<Map<String, Object>> entity = chatClient.prompt()
                .user(userText)
                .call()
                .entity(new ParameterizedTypeReference<List<Map<String, Object>>>() {
                });
        log.info("<entitySample entity>{}", entity);
    }
}
